package com.sunshine.scw.base.util;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
import net.sf.json.util.PropertyFilter;

import org.apache.commons.beanutils.BeanUtils;

public class JsonUtils {

	/**
	 * 从json对象字符串格式中得到一个对象
	 */
	public static <T> T toBean(String jsonString, Class<T> beanClass) {
		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		return (T) jsonObject.toBean(jsonObject, beanClass);
	}

	/**
	 * 从json对象字符串格式中得到一个对象
	 */
	public static <T> T toBean(String jsonString, Class<T> beanClass, Map map) {
		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		return (T) jsonObject.toBean(jsonObject, beanClass, map);
	}

	/**
	 * 将json字符串反序列化为主从关系的实体
	 * 
	 * @param jsonString
	 *            json字符串
	 * @param beanClass
	 *            主实体类型
	 * @param detailClass
	 *            存放了多个从实体在主实体中属性名称和类型
	 * @return
	 */
	public static <T> T toBean(String jsonString, Class<T> beanClass,
			HashMap detailClass) {
		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		T mainEntity = JsonUtils.toBean(jsonString, beanClass);
		for (Object key : detailClass.keySet()) {
			Class value = (Class) detailClass.get(key);
			try {
				BeanUtils.setProperty(mainEntity, key.toString(), value);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return mainEntity;
	}

	/**
	 * 从json字符串得到List集合对象
	 */
	public static <T> List toArrayList(String jsonString, Class<T> beanClass) {
		JSONArray jsonArray = JSONArray.fromObject(jsonString, getJsonConfig());
		List list = new ArrayList();
		for (Iterator iterator = jsonArray.iterator(); iterator.hasNext();) {
			JSONObject jsonObject = (JSONObject) iterator.next();
			list.add(jsonObject.toBean(jsonObject, beanClass));
		}
		return list;
	}

	/**
	 * 从json字符串得到List集合对象,其中对象中包含有Map集合
	 */
	public static <T> List toArrayList(String jsonString, Class<T> beanClass,
			Map map) {
		JSONArray jsonArray = JSONArray.fromObject(jsonString);
		List list = new ArrayList();
		for (Iterator iterator = jsonArray.iterator(); iterator.hasNext();) {
			JSONObject jsonObject = (JSONObject) iterator.next();
			list.add(jsonObject.toBean(jsonObject, beanClass, map));
		}
		return list;
	}

	/**
	 * 将json字符串转化为Map集合对象
	 */
	public static Map toHashMap(String jsonString) {
		Map data = new HashMap();
		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		Iterator it = jsonObject.keys();
		while (it.hasNext()) {
			String key = String.valueOf(it.next());
			Object value = jsonObject.get(key);
			data.put(key, value);
		}
		return data;
	}

	/**
	 * 将json字符串转换为List<Map>形式的对象
	 * 
	 * @return 返回非实体类型(Map)的List
	 */
	public static List<Map> toList(String jsonString) {
		List<Map> list = new ArrayList<Map>();
		JSONArray jsonArray = JSONArray.fromObject(jsonString);
		for (Iterator iterator = jsonArray.iterator(); iterator.hasNext();) {
			JSONObject jsonObject = (JSONObject) iterator.next();
			Map map = new HashMap();
			Iterator it = jsonObject.keys();
			while (it.hasNext()) {
				String key = (String) it.next();
				Object value = jsonObject.get(key);
				map.put(key, value);
			}
			list.add(map);
		}
		return list;
	}

	public static String getJSONString(List<?> list) {
		JSONArray jsonArray = JSONArray.fromObject(list, getJsonConfig());
		return jsonArray.toString();
	}

	/**
	 * 把数据对象转换成JSON字符串
	 * 
	 * @param fields
	 *            要过滤的属性名称数组
	 * @param ignoreCollection
	 *            是否要过滤集合
	 * @return
	 */
	public static String getJSONString(Object object, String dateFormat,
			String[] fields, boolean ignoreCollection) {
		String jsonString = null;
		if (dateFormat == null) {
			dateFormat = "yyyy-MM-dd";
		}
		JsonConfig jsonConfig = getJsonConfig();
		jsonConfig.setJsonPropertyFilter(new IgnoreFieldProcessorImpl(fields,
				ignoreCollection));
		if (object != null) {
			if (object instanceof java.util.Collection
					|| object instanceof Object[]) {
				jsonString = JSONArray.fromObject(object, jsonConfig)
						.toString();
			} else {
				jsonString = JSONObject.fromObject(object, jsonConfig)
						.toString();
			}
		}
		return jsonString == null ? "{}" : jsonString;

	}

	public static String getJSONString(Object object, String[] fields,
			boolean ignoreCollection) {
		return getJSONString(object, null, fields, ignoreCollection);
	}

	public static String getJSONString(Object object, boolean ignoreCollection) {
		return getJSONString(object, null, null, ignoreCollection);
	}

	/**
	 * 把数据对象转换成JSON字符串
	 */
	public static String getJSONStringWithOutFilter(Object object,
			String dateFormat) {
		String jsonString = null;
		if (dateFormat == null)
			dateFormat = "yyyy-MM-dd";
		JsonConfig jsonConfig = getDataFormartToJSON(dateFormat);
		if (object != null) {
			if (object instanceof java.util.Collection
					|| object instanceof Object[]) {
				jsonString = JSONArray.fromObject(object, jsonConfig)
						.toString();
			} else {
				jsonString = JSONObject.fromObject(object, jsonConfig)
						.toString();
			}
		}
		return jsonString == null ? "{}" : jsonString;
	}

	public static String getDefaultJsonString(Object object) {
		return getJSONStringWithOutFilter(object, null);
	}

	private static JsonConfig getJsonConfig() {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.registerJsonValueProcessor(java.util.Date.class,
				new JsonValueProcessorImpl("yyyy-MM-dd"));
		jsonConfig.registerJsonValueProcessor(java.sql.Timestamp.class,
				new JsonValueProcessorImpl("yyyy-MM-dd HH:mm:ss"));
		return jsonConfig;
	}

	private static JsonConfig getDataFormartToJSON(String dateFormart) {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.registerJsonValueProcessor(java.util.Date.class,
				new JsonValueProcessorImpl(dateFormart));
		jsonConfig.registerJsonValueProcessor(java.sql.Timestamp.class,
				new JsonValueProcessorImpl(dateFormart));
		return jsonConfig;
	}

}

/**
 * Json的值的处理加工
 * 
 * @author axiao
 * 
 */
class JsonValueProcessorImpl implements JsonValueProcessor {

	private String format;

	public JsonValueProcessorImpl(String format) {
		this.format = format;
	}

	@Override
	public Object processArrayValue(Object value, JsonConfig config) {
		return null;
	}

	@Override
	public Object processObjectValue(String key, Object value, JsonConfig config) {
		return process(value, config);
	}

	private Object process(Object value, JsonConfig config) {
		if (value instanceof java.util.Date) {
			String str = new SimpleDateFormat(format)
					.format((java.util.Date) value);
			return str;
		}
		if (value instanceof java.sql.Timestamp) {
			String str = new SimpleDateFormat(format)
					.format((java.sql.Timestamp) value);
			return str;
		}
		return value == null ? null : value.toString();
	}

}

/**
 * json属性过滤实现类
 * 
 * @author axiao
 * 
 */
class IgnoreFieldProcessorImpl implements PropertyFilter {

	/* 忽略的属性名称 */
	private String[] fields;

	/* 是否忽略集合 */
	private boolean ignoreCollection;

	public IgnoreFieldProcessorImpl() {
	}

	public IgnoreFieldProcessorImpl(boolean ignoreCollection) {
		this.ignoreCollection = ignoreCollection;
	}

	public IgnoreFieldProcessorImpl(String[] fields, boolean ignoreCollection) {
		this.fields = fields;
		this.ignoreCollection = ignoreCollection;
	}

	/**
	 * 该方法返回false表示过滤该字段，返回false表示可以转换该字段
	 */
	@Override
	public boolean apply(Object source, String name, Object value) {
		boolean flag = false;
		try {
			Method method = source.getClass().getDeclaredMethod(
					getMethodName(name));
			// 忽略集合List和Set
			if (ignoreCollection) {
				if (method.getReturnType().getSimpleName().equals("Set")
						|| method.getReturnType().getSimpleName()
								.equals("List")) {
					flag = true;
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
		}

		// 忽略字段
		if (fields != null && fields.length > 0) {
			for (String field : fields) {
				if (name.equals(field)) {
					flag = true;
				}
			}
		}
		return flag;
	}

	/**
	 * 根据字段名得到该字段的方法名
	 * 
	 * @param fieldName
	 *            字段名
	 * @return 该字段的方法名
	 */
	public String getMethodName(String fieldName) {
		StringBuffer sb = new StringBuffer();
		sb.append("get");
		sb.append(fieldName.substring(0, 1).toUpperCase());
		sb.append(fieldName.substring(1));
		return sb.toString();
	}

	public String[] getFields() {
		return fields;
	}

	public void setFields(String[] fields) {
		this.fields = fields;
	}

	public boolean isIgnoreCollection() {
		return ignoreCollection;
	}

	public void setIgnoreCollection(boolean ignoreCollection) {
		this.ignoreCollection = ignoreCollection;
	}

}
